#include "tree_2_4.h"
#include <string>
#include <iostream>

using namespace std;

Tree_2_4::Tree_2_4 ( void )
{
	height = 0;
	count = 0;
	root = NULL;
}

Tree_2_4::~Tree_2_4 ( void )
{
	Leaf *leaf = firstLeaf;
	
	/* ............ ... .. ...... */

	while ( leaf != NULL )
	{

		/* .. .. ..... .... ....., ... ........ .... ........
		 *... ...... ... ... .... "......" .. ...... ....
		 */

		if ( leaf->HasParent() )
		{
			InnerNode *parent = leaf->parent;

			while ( parent != NULL)
			{
				int i;
				InnerNode *temp;

				for ( i = 0; i < parent->count; i++ )
				{
					Node *child = ( Node * ) parent->pointers[i];
					child->SetParent ( NULL );
				}		

				temp = parent;
				parent = parent->parent;
				delete temp;
			}
		}

		Leaf *temp = leaf;
		leaf = leaf->next;
		delete temp;
	}
}

void Tree_2_4::Insert ( int studentId, string courseId, string courseName, int grade )
{
	Lesson newLesson ( courseId, courseName, grade);

	if ( this->Empty() )
	{			
		root = new Leaf ( NULL , this);
		root->Insert ( studentId, newLesson );
		firstLeaf = (Leaf *) root;

		height = 1;
		count = 1;

		return;
	}
	
	root->Insert (studentId,  newLesson );
}

void Tree_2_4::NewRoot(Node *leftPointer, int leftId, Node *rightPointer, int rightId, bool leaf )
{
	InnerNode *newRoot = new InnerNode(NULL, leftPointer, leftId, rightPointer, rightId, this);
	root = newRoot;

	if ( leaf )
	{	
		firstLeaf = ( Leaf *)leftPointer;
	}

	height++;
}

void Tree_2_4::PrintLessons ( int studentId )
{
	LessonList *lessons;

	lessons = Find ( studentId );
	
	if ( lessons != NULL )
	{
		cout << studentId;
		lessons->Print();
	}
	else
	{
		cout << studentId << " does not exists\n";
	}
}

LessonList *Tree_2_4::Find ( int studentId )
{
	Node *node = root;
	
	int i;

	for ( i = 1; i < height; i++ )
	{
		node = ( Node *) node->GetPointer ( studentId );

		if ( node == NULL )
		{
			return NULL;
		}
	}

	Leaf *leaf = ( Leaf * ) node;

	return leaf->GetLessonList ( studentId );
}

Leaf *Tree_2_4::FindLeaf ( int studentId )
{
	Node *node = root;
	
	int i;

	for ( i = 1; i < height; i++ )
	{
		node = ( Node *) node->GetPointer ( studentId );
	}

	 return ( Leaf * ) node;
}


void Tree_2_4::RangeFind ( int from, int to )
{
	Leaf *leaf = this->FindLeaf ( from );

	leaf->RangePrint ( from, to );
}
void Tree_2_4::Delete ( int studentId, string courseId )
{
	LessonList *lessons = this->Find ( studentId );

	if ( lessons != NULL )
	{
		lessons->Delete ( courseId );	

	}
	else
	{
		cout << "Student with Id: " << studentId << " was not found\n";
	}
}

void Tree_2_4::Delete ( int studentId )
{

	Leaf *leaf = this->FindLeaf ( studentId );
	
	if ( leaf->Has ( studentId ) )	
	{
		leaf->Delete ( studentId );
	}
}

Leaf *Tree_2_4::GetPrevious ( Leaf *targetLeaf)
{
	Leaf *leaf = firstLeaf;

	if ( leaf == targetLeaf )
		return NULL;

	while ( leaf->next != targetLeaf && leaf != NULL )
		leaf = leaf->next;

	return leaf;
}


